#!/bin/bash

# 配置参数
APP_NAME="ResourceOccupier"
JAVA_CMD="java"
JAVA_OPTS="-Xmx12g"
APP_MAIN="ResourceOccupier"
LOG_FILE="app_monitor.log"
CHECK_INTERVAL=10  # 缩短检查间隔为10秒，更快响应进程退出
PID_FILE="app.pid"  # 存储进程PID的文件

# 记录日志函数（带级别）
log() {
    local level=$1
    local message=$2
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] [$level] $message" >> $LOG_FILE
}

# 检查程序是否在运行（更可靠的方式）
is_running() {
    # 方法1：检查PID文件
    if [ -f "$PID_FILE" ]; then
        local pid=$(cat "$PID_FILE")
        # 检查进程是否真的存在
        if ps -p "$pid" > /dev/null; then
            # 进一步确认是我们的Java进程
            if ps -p "$pid" -o cmd --no-headers | grep -q "$APP_MAIN"; then
                return 0  # 运行中
            fi
        fi
        # PID文件存在但进程不存在，删除无效PID文件
        rm -f "$PID_FILE"
        log "WARNING" "发现无效的PID文件，已删除"
    fi

    # 方法2：直接搜索进程
    local pid=$(ps -ef | grep "$APP_MAIN" | grep -v grep | awk '{print $2}')
    if [ -n "$pid" ]; then
        # 验证进程有效性
        if ps -p "$pid" > /dev/null; then
            echo "$pid" > "$PID_FILE"  # 更新PID文件
            return 0  # 运行中
        fi
    fi

    return 1  # 未运行
}

# 启动程序
start_app() {
    log "INFO" "准备启动程序..."
    
    # 确保没有残留进程
    local old_pid=$(ps -ef | grep "$APP_MAIN" | grep -v grep | awk '{print $2}')
    if [ -n "$old_pid" ]; then
        log "WARNING" "发现残留进程 $old_pid，尝试终止..."
        kill -9 "$old_pid" 2>/dev/null
        rm -f "$PID_FILE"
        sleep 2
    fi

    # 启动新进程
    log "INFO" "执行启动命令: $JAVA_CMD $JAVA_OPTS $APP_MAIN"
    nohup $JAVA_CMD $JAVA_OPTS $APP_MAIN >> "$LOG_FILE" 2>&1 &
    
    # 获取并验证新进程PID
    local new_pid=$!
    sleep 3  # 等待启动完成
    
    if ps -p "$new_pid" > /dev/null; then
        echo "$new_pid" > "$PID_FILE"
        log "INFO" "程序启动成功，PID: $new_pid"
        return 0
    else
        log "ERROR" "程序启动失败，PID $new_pid 不存在"
        rm -f "$PID_FILE"
        return 1
    fi
}

# 主监控循环
log "INFO" "监控脚本启动 (PID: $$)，检查间隔: $CHECK_INTERVAL秒"
log "INFO" "监控目标: $APP_MAIN"

while true; do
    if ! is_running; then
        log "ERROR" "程序未在运行或已崩溃，尝试重启..."
        start_app
        # 如果启动失败，增加等待时间避免频繁尝试
        if ! is_running; then
            log "ERROR" "启动失败，将在60秒后再次尝试"
            sleep 60
        fi
    else
        local pid=$(cat "$PID_FILE")
        # 每5分钟记录一次运行状态
        if [ $(( $(date +%s) % 300 )) -eq 0 ]; then
            log "INFO" "程序运行正常，PID: $pid"
        fi
    fi
    sleep $CHECK_INTERVAL
done
